package com.zzjson.strategy.config;

import com.alibaba.dubbo.config.ProtocolConfig;
import com.zzjson.strategy.provider.ApplicationBootstrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.Resource;

import java.util.*;

@Configuration
public class CommonConfiguration implements ApplicationContextAware, DisposableBean {

    private static final Logger logger = LoggerFactory.getLogger(CommonConfiguration.class);

    private ApplicationContext applicationContext;
    private static final Set<SourceLocation> sourceLocations = new HashSet<>();

    static {
        sourceLocations.add(new SourceLocation("dev", "classpath:/config/develop.properties"));
        sourceLocations.add(new SourceLocation("pro", "classpath:/config/release.properties"));
        sourceLocations.add(new SourceLocation("pro-file", "classpath:/config/application.properties"));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Bean
    public PropertySourcesPlaceholderConfigurer placeholderConfig() {
        PropertySourcesPlaceholderConfigurer placeholderConfigurer = new CustomizedPropertySourcesPlaceholderConfigurer();
        placeholderConfigurer.setIgnoreResourceNotFound(true);
        // Local properties
        Properties localProps = new Properties();
        localProps.setProperty("defaultEncoding", "UTF-8");
        localProps.setProperty("defaultLocale", "zh_CN");
        placeholderConfigurer.setProperties(localProps);
        // Resources
        String[] activeProfiles = applicationContext.getEnvironment().getActiveProfiles();
        List<Resource> locationResources = new ArrayList<>();
        for (String activeProfile : activeProfiles) {
            for (SourceLocation sourceLocation : sourceLocations) {
                if (activeProfile.equals(sourceLocation.getProfile())) {
                    locationResources.add(applicationContext.getResource(sourceLocation.getLocation()));
                }
            }
        }
        placeholderConfigurer.setLocations(locationResources.toArray(new Resource[locationResources.size()]));
        return placeholderConfigurer;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("-----------------销毁了呀");
        ProtocolConfig.destroyAll();
        try {
            ApplicationBootstrap.LOCK.lock();
            ApplicationBootstrap.STOP.signal();
        } finally {
            ApplicationBootstrap.LOCK.unlock();
        }
    }

    private static final class SourceLocation {
        private final String profile;
        private final String location;

        public SourceLocation(String profile, String location) {
            this.profile = profile;
            this.location = location;
        }

        public String getProfile() {
            return profile;
        }

        public String getLocation() {
            return location;
        }

        @Override
        public boolean equals(Object obj) {
            return (obj instanceof SourceLocation) &&
                    (obj == this ||
                            (profile.equals(((SourceLocation) obj).getProfile()) &&
                                    location.equals(((SourceLocation) obj).getLocation())));
        }

        @Override
        public int hashCode() {
            return profile.hashCode() + location.hashCode();
        }

        @Override
        public String toString() {
            return profile + ":" + location;
        }
    }
}
